#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class LyricScene:
    """
    """
    
    def __init__(self):
        """
        """
        # setup the default values
        self.line_margin           = 5
        self.scene                 = QGraphicsScene()
        self.lyrics                = []
        self.curr_time_ms          = 0
        self.last_time_ms          = 0
        self.last_hl_index         = 0
        # fonts, there are size information in the object
        self.lyric_font            = QFont()
        # color information
        self.lyric_color           = QColor(255, 255, 255)
        self.lyric_highlight_color = QColor(255, 0, 0)
        # maintain the graphics item in scene
        self.text_items            = []
        self.max_width_no_margin   = 0
        self.lyrics_height         = 0
        self.time_min              = 0
        self.time_max              = 0
        
        self.set_bg_color(QColor(0, 0, 255))

        self.lyric_font.setPixelSize(16)

    def set_line_margin(self, margin):
        """
        
        Arguments:
        - `self`:
        - `margin`:
        """
        if margin >= 0 and self.line_margin != margin:
            self.line_margin = margin
            self._layout_texts()
            self._reset_texts_color()

    def set_bg_color(self, color):
        """
        
        Arguments:
        - `self`:
        - `color`:
        """
        self.scene.setBackgroundBrush(QBrush(color))

    def set_lyric_font(self, font):
        """
        
        Arguments:
        - `self`:
        - `font`:
        """
        if self.lyric_font != font:
            self.lyric_font = font
            self._layout_texts()
            self._reset_texts_color()

    def _get_highlight_index(self):
        """ 根据 self.curr_time_ms 计算出高亮行
        
        Arguments:
        - `self`:
        """
        nr = len(self.lyrics)

        if nr == 0:
            return 0

        t = self.curr_time_ms
        if t < self.lyrics[0][0]:
            return 0

        for i in range(0, nr - 1):
            if t >= self.lyrics[i][0] and t < self.lyrics[i + 1][0]:
                return i

        return nr - 1

    def _layout_texts(self):
        """ 居中布局歌词
        
        Arguments:
        - `self`:
        """

        # 设定字体，并且计算最长的行
        max_width = 0
        for item in self.text_items:
            item.setFont(self.lyric_font)
            w = item.boundingRect().width()
            if max_width < w:
                max_width = w

        self.max_width_no_margin = max_width

        # 开始布局
        height = self.line_margin
        for item in self.text_items:
            w = item.boundingRect().width()
            h = item.boundingRect().height()
            wdiff = self.max_width_no_margin - w
            x = wdiff / 2
            item.setPos(float(x), float(height))
            height += h + self.line_margin

        self.lyrics_height = height

    def _reset_texts_color(self):
        """
        
        Arguments:
        - `self`:
        """
        for item in self.text_items:
            item.setBrush(QBrush(self.lyric_color))

        if self.last_hl_index >= 0 and self.last_hl_index < len(self.text_items):
            self.text_items[self.last_hl_index].setBrush(QBrush(self.lyric_highlight_color))

    def set_lyrics(self, lyrics):
        """ 更新歌词
        
        Arguments:
        - `self`:
        - `lyrics`:
        """
        self.lyrics = lyrics

        self.text_items = []
        self.scene.clear()

        self.curr_time_ms  = 0
        self.last_time_ms  = 0
        self.last_hl_index = 0

        nr = len(lyrics)
        if nr > 0:
            self.time_min = lyrics[0][0]
            self.time_max = lyrics[nr - 1][0]
        else:
            self.time_min = 0
            self.time_max = 0

        for lyric in lyrics:
            if len(lyric[1]) == 0:
                s = " "
            else:
                s = lyric[1]
            item = QGraphicsSimpleTextItem(s)
            self.scene.addItem(item)
            self.text_items.append(item)

        self._layout_texts()
        self._reset_texts_color()

    def set_time_ms(self, time_ms):
        """
        
        Arguments:
        - `self`:
        - `time_ms`:
        """
        if time_ms != self.last_time_ms:
            self.curr_time_ms = time_ms
            hl_idx = self._get_highlight_index()
            if hl_idx != self.last_hl_index:
                self.last_hl_index = hl_idx
                self.last_time_ms = time_ms

                self._reset_texts_color()

if __name__ == '__main__':
    import sys
    from lrcparser import LrcParser
    from lyricviewer import LyricViewer

    codec = QTextCodec.codecForName("utf8")
    QTextCodec.setCodecForLocale(codec)
    QTextCodec.setCodecForCStrings(codec)

    app = QApplication(sys.argv)

    orig_lrc_text = None
    try:
        h = open("youarebeautiful.lrc")
        orig_lrc_text = h.read()
        h.close()
    except:
        print "open test.lrc failed\n"
        sys.exit(1)

    parser = LrcParser()
    parser.set_text(orig_lrc_text)
    parser.parse()

    if len(parser.result) == 0:
        print "invalid lrc format...\n"
        sys.exit(1)

    for lyric in parser.result:
        print "%d %s" % (lyric[0], lyric[1])

    lyric_scene = LyricScene()
    view = LyricViewer(lyric_scene);

    lyric_scene.set_lyrics(parser.result)

    font = QFont()
    font.setPixelSize(24)
    lyric_scene.set_lyric_font(font)

    view.start()

    view.show();
    sys.exit(app.exec_())

